// -----------------------------------------------------------------------
// <copyright file="AddressManager.cs" company="Imar.Spaanjaars.Com">
//   Copyright 2008 - 2009 - Imar.Spaanjaars.Com. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.ComponentModel;
using Spaanjaars.ContactManager.BusinessEntities;
using Spaanjaars.ContactManager.Dal;
using Spaanjaars.Validation;

namespace Spaanjaars.ContactManager.Bll
{
	/// <summary>
	/// The AddressManager class is responsible for managing BusinessEntities.Address objects in the system.
	/// </summary>
	[DataObjectAttribute()]
	public static class AddressManager
	{
		#region Public Methods

		/// <summary>
		/// Gets a list with Address objects for the requested contact person.
		/// </summary>
		/// <param name="contactPersonId">The ID of the ContactPerson for whom the addresses should be returned.</param>
		/// <returns>A list with address objects when the database contains addresses for the contact person, or an empty list otherwise.</returns>
		[DataObjectMethod(DataObjectMethodType.Select, true)]
		public static AddressCollection GetList(int contactPersonId)
		{
			return GetList(contactPersonId, string.Empty);
		}

		/// <summary>
		/// Gets a list with Address objects for the requested contact person.
		/// </summary>
		/// <param name="contactPersonId">The ID of the ContactPerson for whom the addresses should be returned.</param>
		/// <param name="sortExpression">A string containing the expression to sort on. Can contain desc to indicarte descneding order.</param>
		/// <returns>A list with address objects when the database contains addresses for the contact person, or an empty list otherwise.</returns>
		[DataObjectMethod(DataObjectMethodType.Select, false)]
		public static AddressCollection GetList(int contactPersonId, string sortExpression)
		{
			AddressCollection myCollection = AddressDB.GetList(contactPersonId);
			if (!string.IsNullOrEmpty(sortExpression))
			{
				myCollection.Sort(new AddressComparer(sortExpression));
			}
			return myCollection;
		}

		/// <summary>
		/// Gets a single Address from the database by its ID.
		/// </summary>
		/// <param name="id">The unique ID of the address in the database.</param>
		/// <returns>An Address object when the ID exists in the database, or <see langword="null"/> otherwise.</returns>
		[DataObjectMethod(DataObjectMethodType.Select, false)]
		public static Address GetItem(int id)
		{
			return AddressDB.GetItem(id);
		}

		/// <summary>
		/// Saves an address in the database.
		/// </summary>
		/// <param name="myAddress">The Address instance to save.</param>
		/// <returns>The new ID if the Address is new in the database or the existing ID when an item was updated.</returns>
		[DataObjectMethod(DataObjectMethodType.Update | DataObjectMethodType.Insert, true)]
		public static int Save(Address myAddress)
		{
			if (!myAddress.Validate())
			{
				throw new InvalidSaveOperationException("Can't save an invalid Address. Please make sure Validate() returns true before you call Save.");
			}
			myAddress.Id = AddressDB.Save(myAddress);
			return myAddress.Id;
		}

		/// <summary>
		/// Deletes an address from the database.
		/// </summary>
		/// <param name="myAddress">The Address instance to delete.</param>
		/// <returns>Returns <c>true</c> when the object was deleted successfully, or <c>false</c> otherwise.</returns>
		[DataObjectMethod(DataObjectMethodType.Delete, true)]
		public static bool Delete(Address myAddress)
		{
			return AddressDB.Delete(myAddress.Id);
		}

		#endregion

		#region IComparable

		/// <summary>
		/// Implements IComparer&lt;Address&gt; to allow Address objects to be sorted.
		/// </summary>
		private class AddressComparer : IComparer<Address>
		{
			private string _sortColumn;
			private bool _reverse;
			/// <summary>
			/// Constructor for the AddressComparer class that expects the property of the Address class to sort on.
			/// </summary>
			/// <param name="sortExpression">Contains the property of the Address class to sort on. Append [space]desc to sort in reversed order.</param>
			public AddressComparer(string sortExpression)
			{
				if (string.IsNullOrEmpty(sortExpression))
				{
					sortExpression = "Id desc";
				}
				_reverse = sortExpression.ToUpperInvariant().EndsWith(" desc", StringComparison.OrdinalIgnoreCase);
				if (_reverse)
				{
					_sortColumn = sortExpression.Substring(0, sortExpression.Length - 5);
				}
				else
				{
					_sortColumn = sortExpression;
				}
			}

			/// <summary>
			/// Compares two instances of Address.
			/// </summary>
			/// <param name="x">The left hand side Address object.</param>
			/// <param name="y">The right hand side Address object.</param>
			public int Compare(Address x, Address y)
			{
				int retVal = 0;
				switch (_sortColumn.ToUpperInvariant())
				{
					case "ID":
						retVal = x.Id.CompareTo(y.Id);
						break;
					case "STREET":
						retVal = string.Compare(x.Street, y.Street, StringComparison.OrdinalIgnoreCase);
						break;
					case "HOUSENUMBER":
						retVal = string.Compare(x.HouseNumber, y.HouseNumber, StringComparison.OrdinalIgnoreCase);
						break;
					case "ZIPCODE":
						retVal = string.Compare(x.ZipCode, y.ZipCode, StringComparison.OrdinalIgnoreCase);
						break;
					case "CITY":
						retVal = string.Compare(x.City, y.City, StringComparison.OrdinalIgnoreCase);
						break;
					case "COUNTRY":
						retVal = string.Compare(x.Country, y.Country, StringComparison.OrdinalIgnoreCase);
						break;
					case "TYPE":
						retVal = x.Type.CompareTo(y.Type);
						break;
					case "CONTACTPERSONID":
						retVal = x.ContactPersonId.CompareTo(y.ContactPersonId);
						break;
				}
				int _reverseInt = 1;
				if ((_reverse))
				{
					_reverseInt = -1;
				}
				return (retVal * _reverseInt);
			}
		}
		#endregion
	}
}


